<!DOCTYPE html>
<html>
<head>
    <title>Projectile Trajectories and Envelope</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-color: #f0f0f0;
        }
        canvas {
            border: 1px solid #ccc;
            background-color: #fff;
        }
    </style>
</head>
<body>
    <canvas id="physicsCanvas" width="450" height="400"></canvas>
    <script>
        const canvas = document.getElementById('physicsCanvas');
        const ctx = canvas.getContext('2d');

        // Define origin
        const ox = 150;
        const oy = 220;

        // Function to draw axes
        function drawAxes() {
            ctx.beginPath();
            ctx.strokeStyle = '#000';
            ctx.lineWidth = 1;

            // Y-axis
            ctx.moveTo(ox, 30);
            ctx.lineTo(ox, 380);
            // Arrow for y-axis
            ctx.moveTo(ox - 5, 40);
            ctx.lineTo(ox, 30);
            ctx.lineTo(ox + 5, 40);
            
            // X-axis
            ctx.moveTo(30, oy);
            ctx.lineTo(420, oy);
            // Arrow for x-axis
            ctx.moveTo(410, oy - 5);
            ctx.lineTo(420, oy);
            ctx.lineTo(410, oy + 5);
            
            ctx.stroke();

            // Labels
            ctx.font = 'italic 20px Times New Roman';
            ctx.fillStyle = '#000';
            ctx.fillText('y', ox - 25, 45);
            ctx.fillText('x', 425, oy + 8);
            ctx.fillText('O', ox - 25, oy + 25);
        }

        // Function to draw trajectories (solid lines)
        function drawTrajectories() {
            ctx.beginPath();
            ctx.lineWidth = 2;
            ctx.strokeStyle = '#000';

            // Trajectory 1 (highest)
            ctx.moveTo(ox, oy);
            ctx.quadraticCurveTo(ox + 45, oy - 110, ox + 150, oy + 100);

            // Trajectory 2
            ctx.moveTo(ox, oy);
            ctx.quadraticCurveTo(ox + 80, oy - 90, ox + 200, oy + 100);

            // Trajectory 3
            ctx.moveTo(ox, oy);
            ctx.quadraticCurveTo(ox + 110, oy - 60, ox + 240, oy + 100);
            
            // Trajectory 4 (lowest)
            ctx.moveTo(ox, oy);
            ctx.quadraticCurveTo(ox + 130, oy - 30, ox + 260, oy + 100);

            ctx.stroke();
        }

        // Function to draw the envelope (dashed line)
        function drawEnvelope() {
            ctx.beginPath();
            ctx.lineWidth = 2;
            ctx.strokeStyle = '#000';
            ctx.setLineDash([6, 4]);

            // Using a parabola of the form y = a(x-h)^2 + k that passes through the origin
            // Let the vertex be (h, k) in math coordinates relative to O
            const h = 80; 
            const k = 75; // Peak height
            const a = -k / (h * h);

            // Plot the parabola
            const startX = -70;
            const endX = 220;
            
            let firstPoint = true;
            for (let x = startX; x <= endX; x += 2) {
                const y = a * (x - h) * (x - h) + k;
                const canvasX = ox + x;
                const canvasY = oy - y;
                if (firstPoint) {
                    ctx.moveTo(canvasX, canvasY);
                    firstPoint = false;
                } else {
                    ctx.lineTo(canvasX, canvasY);
                }
            }
            
            ctx.stroke();
            ctx.setLineDash([]); // Reset to solid line
        }

        // Function to draw the label for the envelope
        function drawLabel() {
            ctx.font = '24px KaiTi'; // A common Chinese font for calligraphy style
            ctx.fillStyle = '#000';
            ctx.fillText('包络线', 280, 115);
        }

        // --- Main drawing execution ---
        drawAxes();
        drawEnvelope();
        drawTrajectories();
        drawLabel();

    </script>
</body>
</html>